package com.gilight.base.controller;

import com.alibaba.fastjson.JSON;
import com.gilight.base.base.JwtUserToken;
import com.gilight.base.base.LoginUserInfo;
import com.gilight.base.base.ResultEntity;
import com.gilight.base.common.BzdmConstant;
import com.gilight.base.common.RoleStatus;
import com.gilight.base.component.CacheComponent;
import com.gilight.base.config.RedisSessionDAO;
import com.gilight.base.config.jwt.common.Constant;
import com.gilight.base.config.jwt.exception.CustomUnauthorizedException;
import com.gilight.base.config.jwt.util.JwtTokenUtil;
import com.gilight.base.config.jwt.util.JwtUtil;
import com.gilight.base.dao.SysUserAccessLogMapper;
import com.gilight.base.dao.SysUserZzjgMapper;
import com.gilight.base.dto.UserDto;
import com.gilight.base.model.SysRole;
import com.gilight.base.model.SysUser;
import com.gilight.base.service.SysRoleService;
import com.gilight.base.service.SysUserZzjgService;
import com.gilight.base.service.UserService;
import com.gilight.base.service.freight.KdniaoTrackQueryAPI;
import com.gilight.base.util.MapUtils;
import com.gilight.base.util.ShiroUtil;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/web/user")
public class UserController {

    @Autowired
    private UserService userServiceImpl;
    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysUserAccessLogMapper sysUserAccessLogMapper;

    @Autowired
    SysUserZzjgService sysUserZzjgService;

    @Autowired
    RedisSessionDAO redisSessionDAO;
    @Autowired
    KdniaoTrackQueryAPI kdniaoTrackQueryAPI;
    @Autowired
    private CacheComponent cacheComponent;
    @Value("${refreshTokenExpireTime}")
    private Integer refreshTokenExpireTime;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private SysUserZzjgMapper sysUserZzjgMapper;

    @RequestMapping(value = "/login", method = {RequestMethod.POST, RequestMethod.GET})
    public ResultEntity login(@RequestBody @Validated SysUser sysUser, HttpServletResponse httpServletResponse) {
//        ResultEntity resultEntity = new ResultEntity();
//        userServiceImpl.login(sysUser);
//        LoginUserInfo loginUser = (LoginUserInfo)SecurityUtils.getSubject().getPrincipal();
//        Timestamp timestamp = new Timestamp(new Date().getTime());
//        JwtUser jwtUser = new JwtUser(loginUser.getId(),loginUser.getUserName(),loginUser.getPassword(),"","","","",-1L,String.valueOf(loginUser.getRoleId()),true,timestamp);
//        this.loginUserRoles(loginUser);
//        String token = jwtTokenUtil.generateToken(jwtUser);
//        loginUser.setToken(token);
//        redisSessionDAO.doCreate(token,jwtUser);
//        resultEntity.setData(loginUser);
//        return resultEntity;
        // 查询数据库中的帐号信息
        SysUser userDtoTemp = new SysUser();
        userDtoTemp = userServiceImpl.selectByUserCode(sysUser.getUserCode());
        String password = userDtoTemp.getPassword();
        if (userDtoTemp == null) {
            throw new CustomUnauthorizedException("该帐号不存在(The account does not exist.)");
        }
        String md5Password = "";
        try {
            md5Password = kdniaoTrackQueryAPI.MD5(sysUser.getPassword(),"utf8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 密码进行AES解密
        // 因为密码加密是以帐号+密码的形式进行加密的，所以解密后的对比是帐号+密码
        if (md5Password.equals(password)) {
            JwtUserToken jwtUserToken = new JwtUserToken();
            BeanUtils.copyProperties(userDtoTemp,jwtUserToken);
            // 清除可能存在的Shiro权限信息缓存
            if (cacheComponent.hasKey(Constant.PREFIX_SHIRO_CACHE + jwtUserToken.toString())) {
                cacheComponent.del(Constant.PREFIX_SHIRO_CACHE + jwtUserToken.toString());
            }
            // 设置RefreshToken，时间戳为当前时间戳，直接设置即可(不用先删后设，会覆盖已有的RefreshToken)
            String currentTimeMillis = String.valueOf(System.currentTimeMillis());

            cacheComponent.putObj(Constant.PREFIX_SHIRO_REFRESH_TOKEN + jwtUserToken.toString(), currentTimeMillis, refreshTokenExpireTime);
            // 从Header中Authorization返回AccessToken，时间戳为当前时间戳
            String token = JwtUtil.sign(JSON.toJSONString(jwtUserToken), currentTimeMillis);
            //String token = jwtTokenUtil.generateToken(JSON.toJSONString(jwtUserToken));
            httpServletResponse.setHeader("Authorization", token);
            httpServletResponse.setHeader("Access-Control-Expose-Headers", "Authorization");
            ResultEntity resultEntity = new ResultEntity();
            LoginUserInfo loginUserInfo = new LoginUserInfo();
            BeanUtils.copyProperties(userDtoTemp,loginUserInfo);
            this.loginUserRoles(loginUserInfo);
            loginUserInfo.setToken(token);
            List<Map<String, Object>> uzzjgs = sysUserZzjgMapper.getUserZzjgsByUserId(loginUserInfo.getId());
            if(uzzjgs!=null&&uzzjgs.size()>0){
                Map<String,Object> ujg = uzzjgs.get(0);
                String zzjgId = MapUtils.getString(ujg,"zzjgId");
                String zzjgName = MapUtils.getString(ujg,"zzjgName");
                loginUserInfo.setZzjgId(zzjgId);
                loginUserInfo.setZzjgName(zzjgName);
            }
            if(loginUserInfo.getUserName().equals("admin")&& StringUtils.isEmpty(loginUserInfo.getZzjgId())){
                loginUserInfo.setZzjgName("总部");
                loginUserInfo.setZzjgId("1");
            }
            resultEntity.setData(loginUserInfo);
            return resultEntity;
        } else {
            throw new CustomUnauthorizedException("帐号或密码错误(Account or Password Error.)");
        }
    }

    @RequestMapping(value = "/stulogin", method = {RequestMethod.POST, RequestMethod.GET})
    public ResultEntity stulogin(@RequestBody @Validated SysUser sysUser) {
        ResultEntity resultEntity = new ResultEntity();
        userServiceImpl.login(sysUser);
        LoginUserInfo loginUser = (LoginUserInfo)SecurityUtils.getSubject().getPrincipal();
        // 验证当前登录人是否存在报考信息，如果不存在，不允许进入系统
        userServiceImpl.selectStudentByExamineeNumber(loginUser.getUserCode());
        this.loginUserRoles(loginUser);
        resultEntity.setData(loginUser);
        return resultEntity;
    }

    @RequestMapping(value = "/test", method = {RequestMethod.GET})
    public ResultEntity test() {
        ResultEntity resultEntity = new ResultEntity();
        LoginUserInfo loginUser = (LoginUserInfo)SecurityUtils.getSubject().getPrincipal();
        System.out.println(loginUser.getUserCode()+","+loginUser.getUserName());
        resultEntity.setData(loginUser);
        return resultEntity;
    }

    @RequestMapping(value = "/logout", method = {RequestMethod.POST, RequestMethod.GET})
    public ResultEntity logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return new ResultEntity("操作成功");
    }

    @RequestMapping(value = "/checkLogin", method = {RequestMethod.POST, RequestMethod.GET})
    public ResultEntity hello() {
        //统一认证登录接口,如果shiro没拦截就是登录了
        ResultEntity resultEntity = new ResultEntity();
        SysUser user = ShiroUtil.getJWTUser();
        LoginUserInfo loginUserInfo = new LoginUserInfo();
        BeanUtils.copyProperties(user,loginUserInfo);
        this.loginUserRoles(loginUserInfo);
        String loginStr = JSON.toJSONString(loginUserInfo);
        Map map = JSON.parseObject(loginStr, Map.class);
        List<Map<String, Object>> deptList = sysUserZzjgService.getCurrentUserZzjgs();
        map.put("deptList",deptList);
        resultEntity.setData(map);
        return resultEntity;
    }

    @RequestMapping(value = "/findList", method = {RequestMethod.POST, RequestMethod.GET})
    public ResultEntity findList(@RequestBody @Validated UserDto userDto) {
        ResultEntity resultEntity = new ResultEntity();
        PageInfo page = userServiceImpl.findList(userDto);
        resultEntity.setData(page);
        return resultEntity;
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public ResultEntity add(@RequestBody SysUser sysUser) {
        ResultEntity resultEntity = new ResultEntity();
        userServiceImpl.addUser(sysUser);
        return resultEntity;
    }

    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public ResultEntity edit(@RequestBody SysUser sysUser) {
        ResultEntity resultEntity = new ResultEntity();
        userServiceImpl.edit(sysUser);
        return resultEntity;
    }

    //批量删除多个用户
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public ResultEntity delete(@RequestBody Map<String, Object> map) {
        ResultEntity resultEntity = new ResultEntity();
        userServiceImpl.delete(map);
        return resultEntity;
    }

    @RequestMapping(value = "/resetPassword", method = RequestMethod.GET)
    public ResultEntity resetPassword(@RequestParam Long id) {
        ResultEntity resultEntity = new ResultEntity();
        userServiceImpl.resetPassword(id);
        return resultEntity;
    }

    @RequestMapping(value = "/updatePassword", method = RequestMethod.POST)
    public ResultEntity updatePassword(@RequestBody SysUser sysUser) {
        ResultEntity resultEntity = new ResultEntity();
        userServiceImpl.updatePassword(sysUser);
        return resultEntity;
    }

    @RequestMapping(value = "/enable", method = RequestMethod.GET)
    public ResultEntity enable(@RequestParam Long id) {
        ResultEntity resultEntity = new ResultEntity();
        userServiceImpl.updateStatus(id, RoleStatus.ENABLE);
        return resultEntity;
    }

    @RequestMapping(value = "/disable", method = RequestMethod.GET)
    public ResultEntity disable(@RequestParam Long id) {
        ResultEntity resultEntity = new ResultEntity();
        userServiceImpl.updateStatus(id, RoleStatus.DISABLE);
        return resultEntity;
    }

    @RequestMapping(value = "/assign", method = { RequestMethod.POST, RequestMethod.GET })
    @CacheEvict(value = BzdmConstant.REDIS_LOADMENU, key = "#id")
    public ResultEntity assign(Long id, String roleIds) {
        ResultEntity resultEntity = new ResultEntity();
        String[] arr = roleIds.split(",");
        List<Long> roleIdList = Arrays.stream(arr).map(Long::parseLong).collect(Collectors.toList());
        userServiceImpl.assign(id, roleIdList);
        return resultEntity;
    }
    private void loginUserRoles(LoginUserInfo loginUser){
        // 加载用户角色
        List<SysRole> roles = sysRoleService.selectByUserId(loginUser.getId());
        Long roleId = sysRoleService.selectDefaultRoleByUserId(loginUser.getId());
        List<Map<String, Object>> buttons = sysRoleService.findAllButtonPermission(roleId);
        //设置默认角色额
        loginUser.setRoleId(roleId);
        //设置按钮权限
        loginUser.setButtons(buttons);
        //设置用户拥有的角色
        loginUser.setRoles(roles);
    }

    /**
     * @Author lousk
     * @Description 获取当前登录用户和用户所在部门
     * @Date 2020/11/3
     * @Time 11:06
     * @return com.gilight.base.base.ResultEntity
     */
    @RequestMapping(value = "/getCurrentUserAndDept", method = RequestMethod.GET)
    public ResultEntity getCurrentUserAndDept() {
        ResultEntity resultEntity = new ResultEntity();
        Map map = userServiceImpl.getCurrentUserAndDept();
        resultEntity.setData(map);
        return resultEntity;
    }

    /**
     * 测试接口
     */
    @RequestMapping(value = "/getProps", method = {RequestMethod.GET})
    public ResultEntity getProps() {
        ResultEntity resultEntity = new ResultEntity();
        SysUser sysUser = ShiroUtil.getUser();
        String userCode = sysUser.getUserCode();
        Map<String, Object> map = userServiceImpl.getProps(userCode);
        if (map == null) {
            //测试
            map = new HashMap<>();
            map.put("xh","170102801201");
            map.put("xm","张三");
            map.put("yx","智能财经学院");
            map.put("zy","财务管理");
            map.put("zydm","630301");
            map.put("bj","智能财经学院");
            map.put("bjdm","170102");
            map.put("xb","男");
            map.put("xbdm","1");
        }
        resultEntity.setData(map);
        return resultEntity;
    }
}
